package cn.mill.support.http;

import java.nio.charset.CodingErrorAction;
import java.util.Arrays;

import javax.net.ssl.SSLContext;

import org.apache.http.client.HttpClient;
import org.apache.http.client.HttpRequestRetryHandler;
import org.apache.http.client.config.AuthSchemes;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.config.ConnectionConfig;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.config.SocketConfig;
import org.apache.http.conn.HttpConnectionFactory;
import org.apache.http.conn.ManagedHttpClientConnection;
import org.apache.http.conn.routing.HttpRoute;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.ManagedHttpClientConnectionFactory;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.ssl.SSLContexts;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class HttpConnectionManager {
	private static final Logger logger = LoggerFactory.getLogger(HttpConnectionManager.class);
	
	private static HttpConnectionFactory<HttpRoute, ManagedHttpClientConnection> connFactory = new ManagedHttpClientConnectionFactory();
	private static SSLContext sslcontext = SSLContexts.createSystemDefault();
	private static Registry<ConnectionSocketFactory> socketFactoryRegistry =
			RegistryBuilder.<ConnectionSocketFactory> create().register("http", PlainConnectionSocketFactory.INSTANCE).register("https", new SSLConnectionSocketFactory(sslcontext)).build();
	
	private static PoolingHttpClientConnectionManager poolConnectionManager = new PoolingHttpClientConnectionManager(socketFactoryRegistry, connFactory);
	private static RequestConfig defaultRequestConfig =
			RequestConfig.custom().setExpectContinueEnabled(true).setTargetPreferredAuthSchemes(Arrays.asList(AuthSchemes.NTLM, AuthSchemes.DIGEST)).setProxyPreferredAuthSchemes(Arrays.asList(AuthSchemes.BASIC)).build();
	// 自动重试策略
	private static HttpRequestRetryHandler customHttpRequestRetryHandler = new SupportHttpRequestRetryHandler();
	
	static {
		SocketConfig socketConfig = SocketConfig.custom().setTcpNoDelay(true).build();
		poolConnectionManager.setDefaultSocketConfig(socketConfig);
		
		ConnectionConfig connectionConfig = ConnectionConfig.custom().setMalformedInputAction(CodingErrorAction.IGNORE).setUnmappableInputAction(CodingErrorAction.IGNORE).build();
		
		poolConnectionManager.setDefaultConnectionConfig(connectionConfig);
		
		poolConnectionManager.setMaxTotal(200);
		poolConnectionManager.setDefaultMaxPerRoute(20);
	}
	
	public static HttpClient getHttpClient() {
		logger.debug("get  http client  ");
		CloseableHttpClient httpclient = HttpClients.custom().setConnectionManager(poolConnectionManager).setDefaultRequestConfig(defaultRequestConfig).setRetryHandler(customHttpRequestRetryHandler).build();
		return httpclient;
	}
}
